package com.xiao.train.common.controller;

import cn.hutool.core.util.StrUtil;
import com.xiao.train.common.exception.BusinessException;
import com.xiao.train.common.resp.CommonResp;
import io.seata.core.context.RootContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@ControllerAdvice
@Slf4j
public class ControllerExceptionHandler {

    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public CommonResp exceptionHandler(BindException e) throws Exception {
        log.info("Seata全局事务ID: {}", RootContext.getXID());
        // 如果在一次全局事务方出异常,就不要包装返回值,直接把异常抛给调用方,让调用方回滚事务
        if (StrUtil.isNotBlank(RootContext.getXID()))
            throw e;
        CommonResp res = new CommonResp();
        List<String> ms = new ArrayList<>();
        for (ObjectError s : e.getBindingResult().getAllErrors())
            ms.add(s.getDefaultMessage());
        log.error("校验异常: {}", ms);
        res.setSuccess(false);
        res.setMessage(ms.toString());
        return res;
    }

    @ExceptionHandler(value = BusinessException.class)
    @ResponseBody
    public CommonResp exceptionHandler(BusinessException e) throws Exception {
        CommonResp res = new CommonResp();
        log.error("业务异常: {}", e.getE().getDesc());
        res.setSuccess(false);
        res.setMessage(e.getE().getDesc());
        return res;
    }

    /**
     * 统一异常
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public CommonResp exceptionHandler(Exception e) throws Exception {
        CommonResp res = new CommonResp();
        log.error("系统异常: ", e);
        res.setSuccess(false);
        res.setMessage("系统异常, 请联系管理员!");
        return res;
    }
}
